package com.zhanghu.backendZray.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhanghu.backendZray.exception.ApiException;
import com.zhanghu.backendZray.pojo.entity.DailyPlan;
import com.zhanghu.backendZray.pojo.entity.DailyTask;
import com.zhanghu.backendZray.pojo.request.dailyPlanTask.DailyPlanPageRequest;
import com.zhanghu.backendZray.pojo.request.dailyPlanTask.DailyPlanRequest;
import com.zhanghu.backendZray.pojo.vo.DailyPlanVo;
import com.zhanghu.backendZray.service.DailyTaskService;
import com.zhanghu.backendZray.service.UserService;
import com.zhanghu.backendZray.mapper.DailyPlanMapper;
import com.zhanghu.backendZray.service.DailyPlanService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author ZhangDong
 * @date 2024/7/7 18:15
 */
@Service
@Slf4j
@AllArgsConstructor
public class DailyPlanServiceImpl extends ServiceImpl<DailyPlanMapper, DailyPlan> implements DailyPlanService {
    private final DailyTaskService dailyTaskService;
    private final UserService userService;

    /**
     * 每日计划执行间隔时间
     * 长期记忆间隔
     */
    private final List<Integer> intervalDayList = ListUtil.of(1, 2, 4, 7, 15, 30, 90, 180);

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(DailyPlanRequest dailyPlanRequest) {
        DailyPlan dailyPlan = new DailyPlan();
        BeanUtil.copyProperties(dailyPlanRequest, dailyPlan, "id");
        dailyPlan.setUserName(userService.getNameById(dailyPlanRequest.getUserId()));
        baseMapper.insert(dailyPlan);
        if (dailyPlanRequest.isAutoCreateTask()) {
            createTask(dailyPlan);
            dailyPlan.setCreatedTask(true);
            baseMapper.updateById(dailyPlan);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void createTask(DailyPlan dailyPlan) {
        Long id = dailyPlan.getId();
        Byte taskType = dailyPlan.getTaskType();
        if (taskType == 0) {
            LocalDate rememberStartDate = dailyPlan.getRememberStartDate();
            Assert.notNull(rememberStartDate, "长期记忆开始日期不能为空");
            List<DailyTask> dailyTaskList = intervalDayList.stream().map(intervalDay -> {
                LocalDate rememberDate = rememberStartDate.plusDays(intervalDay);
                DailyTask dailyTask = new DailyTask();
                dailyTask.setPlanId(id);
                dailyTask.setRememberDate(rememberDate);
                dailyTask.setTaskType(dailyPlan.getTaskType());
                return dailyTask;
            }).collect(Collectors.toList());
            dailyTaskService.saveBatch(dailyTaskList);
        } else if (taskType == 1) {
            LocalDateTime scheduledTaskDateTime = dailyPlan.getScheduledTaskDateTime();
            Assert.notNull(scheduledTaskDateTime, "定时任务时间不能为空");
            Byte aheadMinutes = dailyPlan.getAheadMinutes();
            LocalDateTime needNotifyTime = scheduledTaskDateTime.minusMinutes(Long.valueOf(aheadMinutes));
            DailyTask dailyTask = new DailyTask();
            dailyTask.setPlanId(id);
            dailyTask.setScheduledTaskDateTime(needNotifyTime);
            dailyTask.setTaskType(dailyPlan.getTaskType());
            dailyTaskService.save(dailyTask);
        }
    }

    @Override
    public void update(DailyPlanRequest dailyPlanRequest) {
//        DailyPlan dailyPlan = new DailyPlan();
//        BeanUtil.copyProperties(dailyPlanRequest, dailyPlan, "id");
//        dailyPlanDao.updateByPrimaryKeySelective(dailyPlan);
    }

    @Override
    public void del(Long id) {
        baseMapper.deleteById(id);
    }

    @Override
    public Page<DailyPlanVo> page(DailyPlanPageRequest request) {
        Page<DailyPlanVo> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<DailyPlanVo> list = baseMapper.page(page, request);
        return list;
    }

    @Override
    public DailyPlan getById(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createTask(Long id) {
        DailyPlan plan = getById(id);
        if (plan.getCreatedTask()) {
            throw new ApiException("此计划已创建任务");
        }
        Optional.ofNullable(plan).orElseThrow(() -> new RuntimeException("此计划不存在"));
        createTask(plan);
        plan.setCreatedTask(true);
        baseMapper.updateById(plan);
    }
}
